package cn.itcast.blog.Utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSession;
import cn.itcast.blog.mapper.CategoryMapper;
import cn.itcast.blog.service.CategoryService;
import cn.itcast.blog.service.PostService;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ServiceProxyUtils {
	/**
	 * 传入一个原始的service对象
	 * 返回一个增强过的service对象
	 * 
	 * 增强：在service方法调用之前，打开session
	 * 		在service方法调用之后，关闭session
	 * @return 
	 */
	public static <T> T cretaeProxy(T service) {
		
		Enhancer enhancer = new Enhancer();	//new一个增强器
		
		enhancer.setSuperclass(service.getClass()); //获取到CategoryService的类信息
		
		//方法拦截器
		enhancer.setCallback(new MethodInterceptor() {
			
			@Override
			public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
				//打开session
				SqlSessionFactory sqlSessionFactory = SessionFactoryUtils.getFactory();
				
				SqlSession sqlSession = sqlSessionFactory.openSession();
				
				//反射
				Field field = service.getClass().getDeclaredField("mapper");
				
				Class<?> type = field.getType();
				
				field.setAccessible(true);
				
				//对service里面的mapper赋值，值为sqlSession.getMapper(type)
				field.set(service,sqlSession.getMapper(type));
				
				//原来的方法
				Object invoke = methodProxy.invoke(service, args);
				
				//关闭
				sqlSession.commit();
				sqlSession.close();
				
				return invoke;
			}
		});
		
		//创建代理对象
		T proxy = (T) enhancer.create();
		
		return proxy;
	}
	
}

